#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@author: henry_oulen@163.com
@file: base_requeset.py
@time: 2023/10/27 18:41
@desc: 
"""
import json

import jwt
import tornado
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import scoped_session, sessionmaker
from torndsession.sessionhandler import SessionBaseHandler

from backend.conf import config
from backend.tvadmin.system.models.log import OperationLog
from backend.tvadmin.system.models.permission import User
from backend.tvadmin.system.utils.auth_utils import token_check
from backend.tvadmin.utils.base_response import ErrorResponse
from backend.tvadmin.utils.db_utils import engine
from backend.tvadmin.utils.log_utls import app_log
from backend.tvadmin.utils.redis_utils import RedisBase


class BaseHttpHandler(SessionBaseHandler):

    def __init__(self, application, request, **kwargs):
        super(BaseHttpHandler, self).__init__(application, request, **kwargs)
        self.db = scoped_session(sessionmaker(bind=engine))
        self._session = self.session.session
        self.redis = RedisBase()

    def prepare(self):
        request_body = ""
        if self.request.method == "GET" or self.request.method == "DELETE":
            if self.request.query:
                re_data = dict([item.split('=') for item in self.request.query.split('&')])
                request_body = json.dumps(re_data)
                self.request.data = re_data
            else:
                json.dumps({})
        else:
            request_body = self.request.body
            self.request.data = json.loads(request_body)
        log = dict(
            request_modular=self.request.path,
            request_path=self.request.path,
            request_body=request_body,
            request_method=self.request.method,
            request_msg=self.request.path,
            request_ip=self.request.host,
            request_browser="",
            response_code=200,
            request_os="win",
            json_result="success",
            status=200,
        )
        try:
            operator_log = OperationLog(**log)
            self.db.add(operator_log)
            self.db.commit()  # 需要调用commit()方法提交事务。

        except SQLAlchemyError as e:
            self.db.rollback()

        finally:
            self.db.close()

    def data_received(self, chunk):
        print("hello world")

    def write(self, chunk):
        super(BaseHttpHandler, self).write(chunk)

    def on_finish(self):
        try:
            self.db.commit()
            self.db.close()
        except Exception as e:
            print(e)
            self.db.rollback()
            self.db.close()

    def session_get(self, key, default=None):
        if key in self.session:
            return self._session[key]
        else:
            return default

    def set_default_headers(self):
        """处理跨域问题"""
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "Content-Type,Authorization,x-requested-with")
        self.set_header("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE")

    def options(self):
        """处理预加载问题"""

        self.finish()


# @token_check
# class ApiRequestHandler(BaseHttpHandler):
#     def __init__(self, application, request, **kwargs):
#         super(ApiRequestHandler, self).__init__(application, request, **kwargs)
#         if 'token' in self.session:
#             self.session['token'] = self.session['token']
#             self.session.flush()
#
#     # def data_received(self, chunk):
#     #     pass
#
class BaseSessionBaseHandler(SessionBaseHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.date = None  # 添加自定义属性
        self.user = None  # 添加自定义属性


class BaseAuthCheckHttpHandler(BaseSessionBaseHandler):

    def __init__(self, application, request, **kwargs):
        super(BaseAuthCheckHttpHandler, self).__init__(application, request, **kwargs)
        self.db = scoped_session(sessionmaker(bind=engine))
        self._session = self.session.session
        self.redis = RedisBase()

    def prepare(self):
        try:
            request_body = ""
            if self.request.method == "GET" or self.request.method == "DELETE":
                if self.request.query:
                    re_data = dict([item.split('=') for item in self.request.query.split('&')])
                    request_body = json.dumps(re_data)
                    self.request.data = re_data
                else:
                    json.dumps({})
            else:
                temp = {}
                if not hasattr(self.request, "files"):
                    request_body = self.request.body
                    self.request.data = json.loads(request_body)
                elif self.request.files == temp:
                    request_body = self.request.body
                    self.request.data = json.loads(request_body)
        except Exception as e:
            app_log.error(e)
            self.write(ErrorResponse(status=401, msg="数据验证失败"))
            self.finish()

        log = dict(
            request_modular=self.request.path,
            request_path=self.request.path,
            request_body=request_body,
            request_method=self.request.method,
            request_msg=self.request.path,
            request_ip=self.request.host,
            request_browser="",
            response_code=200,
            request_os="win",
            json_result="success",
            status=200,
        )
        try:
            operator_log = OperationLog(**log)
            self.db.add(operator_log)
            self.db.commit()  # 需要调用commit()方法提交事务。
            self.authenticated_async()


        except SQLAlchemyError as e:
            self.db.rollback()

        finally:
            self.db.close()

    def data_received(self, chunk):
        print("hello world")

    def write(self, chunk):
        super(BaseAuthCheckHttpHandler, self).write(chunk)

    def on_finish(self):
        try:
            self.db.commit()
            self.db.close()
        except Exception as e:
            print(e)
            self.db.rollback()
            self.db.close()

    def session_get(self, key, default=None):
        if key in self.session:
            return self._session[key]
        else:
            return default

    def set_default_headers(self):
        """处理跨域问题"""
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "Content-Type,Authorization,x-requested-with")
        self.set_header("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE")

    def options(self):
        """处理预加载问题"""

        self.finish()

    def authenticated_async(self):
        authorization = self.request.headers.get("Authorization", None)
        if authorization:
            try:
                algorithm = config.algorithm
                authorization_dict = jwt.decode(authorization, self.settings["secret_key"], algorithms=algorithm)
                user_id = authorization_dict.get("id")
                if user_id:
                    user = self.db.query(User).filter(User.id == user_id).first()
                    if user:
                        self.request.user = user
                    else:
                        self.write(ErrorResponse(status=401, msg="用户验证失败"))
                        self.finish()
                else:
                    self.write(ErrorResponse(status=401, msg="用户验证失败"))
                    self.finish()
            except jwt.exceptions.DecodeError as e:
                app_log.info(f"error{e}")
                self.write(ErrorResponse(status=401, msg="用户验证失败"))
                self.finish()
